通过上一章节的学习,我们认识了“可视化苏菲世界”这个分析任务,学习了一个数据分析的模型,并且基于该模型提出了很多想要讨论的问题,甚至已经有了简单的设计手段。
但是在一个完整的数据分析的流程中,我们还处于设计阶段 , 也就是还停留在理论阶段。因此,这一章节我们将进入实现阶段,选择一个问题进行讨论,完成可视化图表的选择,再在浏览器里把它用 Canvas2D 和 SVG 绘制出来,让你更完整和深入地理解数据可视化。
学习是一个循序渐进的过程,所以我们先从一个比较简单的问题入手,来掌握整个实现的流程。基于简单的标准,我们选择的问题是:“哲学家、哲学问题和流派的数量关系是怎样的?”,所以我们去统计了“苏菲的世界”数据集中哲学家、哲学问题和流派的数量,得到的结果如下:
| name | value |
|---|---|
| questions | 17 |
| schools | 25 |
| philosophers | 35 |
想要体现这三者的数量关系,按照通用的数据分析流程,我们需要经过方案设计、数据处理、数据渲染这几个步骤。接下来,我们分别来说。
# 设计方案
上一章节提到的数据分析的模型主要有三部分,我们就用这三个部分的理论来分析一下“哲学家,哲学问题和流派的数量关系是怎样的?”这个问题,从而得出的我们的设计方案。
- 认识数据:这个数据集是表格,每一条数据代表一个实体,每一个实体有明显两个属性:name 是分类属性,value 是一个数值属性。当然也有一个隐藏属性,就是它们在表格里面的索引属性:比 questions 的索引属性是 0, schools 的索引属性是 1,philosophers 的索引属性是 2,索引属性明显是分类属性。
- 确定任务:因为我们不知道它们的关系到底是咋样的,所以这是一个发现任务,对象是哲学家、哲学问题和流派的数量的特征。
- 设计方案:我们可以根据数据属性和任务的种类,去选择合适的可视化图表。一般来说,了解分类数据和数值属性的特征,最好的选择就是条形图。因为条水平方向的位置是分类属性,所以可以将同为分类属性的索引属性映射过去;因为同为数值属性,所以可以把 value 属性映射为条的高度;最后因为相同的道理,可以把 name 属性映射为条的颜色。
提出设计方案之后,在正式开始写代码之前,因为小册子篇幅的限制,我们先来做几个约定,让我们在有限的篇幅内可以给大家讲解更多有价值的东西。
# 开发约定
这里我们先介绍两个开发约定:
第一,在介绍新代码块的时候,不会显式地说新建或者修改文件或者文件夹。 文章中的代码块中的顶部会有包含该代码块文件的地址,这个地址是相对项目根目录的。如果不存在对应的文件夹和文件,就自行新建对应的文件夹或者文件。否则,对该文件夹或者文件进行修改即可。
比如我要加入以下的代码,因为目前项目中没有 hello 这个文件夹和 index.js 这个文件,所以需要新建它们,然后再增加以下的 foo 函数。
// src/hello/index.js
export function foo() {
return 'foo';
}
第二,讲解内容很多会以注释的实行在代码中展现,不会单独说明。这样将需要实现的功能和对应的代码关联起来,一方面可以更加清楚功能的具体代码实现,另一方面也知道这段代码主要解决什么问题。
// index.js
export function foo() {
return 'foo'; // 让调用者知道这是一个 foo 函数
}
当然最后都会把完整且可以运行的代码存储的 Github 仓库分享给大家,大家可以将代码 Clone 下来学习一下。
说了这么多废话,那么接下里我们正式进入开发环节。
# 数据处理
我们首先进入数据处理阶段,这个阶段的核心任务或者难点就是“如何把原始数据转换成可以直接绘制的数据?”,包括 “转换过程分为哪几个阶段?,我们接下来一点点来看。
首先加入如下代码,用来声明我们要可视化的数据和画布的维度信息。
// ch03/barchart/canvas/index.js
const data =